package com.edu.system.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.validation.Validator;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.edu.system.domain.Student;
import com.edu.system.domain.TExamination;
import com.edu.system.domain.TStudyScore;
import com.edu.system.domain.vo.AvgExamSchoolRankVO;
import com.edu.system.domain.vo.ScoreAnalysisVO;
import com.edu.system.domain.vo.ScoreAnalysisVO.LessonAnalysis;
import com.edu.system.mapper.TStudyScoreMapper;
import com.edu.system.service.IStudentService;
import com.edu.system.service.ITExaminationService;
import com.edu.system.service.ITStudyScoreService;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 成绩Service业务层处理
 * 
 * @author xxxx
 * @date 2023-12-29
 */
@Slf4j
@Service
public class TStudyScoreServiceImpl implements ITStudyScoreService 
{
    @Autowired
    private TStudyScoreMapper tStudyScoreMapper;

    @Autowired
    private IStudentService studentService;

    @Autowired
    protected Validator validator;
    @Resource
    private ITExaminationService itExaminationService;

    /**
     * 查询成绩
     * 
     * @param id 成绩主键
     * @return 成绩
     */
    @Override
    public ScoreAnalysisVO selectTStudyScoreById(Long id)
    {
        TStudyScore score = tStudyScoreMapper.selectTStudyScoreById(id);

        List<TStudyScore> details = tStudyScoreMapper.selectTStudyScoreList(
            TStudyScore.builder()
                .examId(score.getExamId())
                .stuNo(score.getStuNo())
                .build());
        if (CollectionUtils.isEmpty(details)){
            return null;
        }

        List<LessonAnalysis> collect = details.stream()
            .filter(a -> !a.getLessonName().equals("总分"))
            .map(a -> {
                LessonAnalysis l = BeanUtil.copyProperties(a, LessonAnalysis.class);
                l.setNum(a.getScore());
                return l;
            })
            .collect(Collectors.toList());

        LessonAnalysis zf = BeanUtil.copyProperties(score, LessonAnalysis.class);
        zf.setNum(score.getScore());
        collect.add(zf);

        return ScoreAnalysisVO.builder()
            .stuNo(score.getStuNo())
            .name(score.getName())
            .totalNum(score.getScore())
            .examTitle(score.getTitle())
            .analyses(collect)
            .build();
    }

    /**
     * 查询成绩列表
     * 
     * @param tStudyScore 成绩
     * @return 成绩
     */
    @Override
    public List<TStudyScore> selectScoreList(TStudyScore tStudyScore)
    {
        return tStudyScoreMapper.selectTStudyScoreList(tStudyScore);
    }

    @Override
    public List<TStudyScore> queryStudyScore(Long studentId, Date startDate, Date endDate) {
        return Optional.ofNullable(studentService.selectStudentById(studentId))
            .map(a -> tStudyScoreMapper.queryStudyScore(a.getStuNo(), "总分", startDate, endDate))
            .orElseGet(ArrayList::new);
    }

    /**
     * 新增成绩
     * 
     * @param scoreList 成绩
     * @return 结果
     */
    @Override
    public int insertTStudyScore(List<TStudyScore> scoreList)
    {
        return tStudyScoreMapper.batchInsert(scoreList);
    }


    /**
     * 修改成绩
     * 
     * @param tStudyScore 成绩
     * @return 结果
     */
    @Override
    public int updateTStudyScore(TStudyScore tStudyScore)
    {
        return tStudyScoreMapper.updateTStudyScore(tStudyScore);
    }

    /**
     * 批量删除成绩
     * 
     * @param ids 需要删除的成绩主键
     * @return 结果
     */
    @Override
    public int deleteTStudyScoreByIds(Long[] ids)
    {
        return tStudyScoreMapper.deleteTStudyScoreByIds(ids);
    }

    /**
     * 删除成绩信息
     * 
     * @param id 成绩主键
     * @return 结果
     */
    @Override
    public int deleteTStudyScoreById(Long id)
    {
        return tStudyScoreMapper.deleteTStudyScoreById(id);
    }

    @Override
    public int deleteByExamId(Long[] examIds) {
        return tStudyScoreMapper.deleteByExamId(examIds);
    }

    @Override
    public String importScore(List<List<String>> scoreList, Long examId, String operName) {

        TExamination exam = itExaminationService.selectTExaminationById(examId);
        Map<Integer, String> nameMap = new HashMap<>();
        List<String> head = scoreList.get(1);
        int s = 5;
        while (s < head.size()){
            nameMap.put(s, head.get(s));
            s += 5;
        }

        List<TStudyScore> res = new ArrayList<>();

        for (int i = 3; i<scoreList.size(); i++){
            List<String> row = scoreList.get(i);
            if (StrUtil.isBlank(row.get(1))){
                break;
            }

            nameMap.forEach((k,v)->{
                if (!NumberUtil.isNumber(row.get(k))){
                    return;
                }
                TStudyScore build = TStudyScore.builder()
                    .stuNo(row.get(1))
                    .name(row.get(3))
                    .examId(examId)
                    .title(exam.getTitle())
                    .examDate(exam.getExamDate())
                    .lessonName(v)
                    .score(Double.parseDouble(row.get(k)))
                    .rankSchool(toInteger(row.get(k + 1)))
                    .upswingSchool(toInteger(row.get(k + 2)))
                    .rankClass(toInteger(row.get(k + 3)))
                    .upswingClass(toInteger(row.get(k + 4)))
                    .build();
                res.add(build);
            });
        }

        List<String> no = res.stream().map(TStudyScore::getStuNo).distinct().collect(Collectors.toList());
        Map<String, Student> existNoMap = studentService.queryByStuNos(no)
            .stream().collect(Collectors.toMap(Student::getStuNo, b -> b, (x, y) -> x));

        int successNum = 0;
        int failureNum = 0;
        StringBuilder msg = new StringBuilder();
        List<TStudyScore> data = new ArrayList<>();
        for (TStudyScore r : res){
            if (!existNoMap.containsKey(r.getStuNo())){
                failureNum++;
                msg.append("<br/>" + failureNum + "、学生 " + r.getName() + " 不存在");
                continue;
            }
            Student ss = existNoMap.get(r.getStuNo());
            if (!ss.getName().equals(r.getName())){
                failureNum++;
                msg.append("<br/>" + failureNum + "、学生 " + r.getName() + " 与学号不符");
                continue;
            }
            // 补充学生信息
            r.setClassId(ss.getClassId());
            successNum++;
            data.add(r);
        }

        // 删除本次导入的学生
        tStudyScoreMapper.deleteScore(examId, no);

        if (CollectionUtils.isNotEmpty(data)){
            this.insertTStudyScore(data);
            if (failureNum > 0){
                msg.insert(0, "<br/>失败：" + failureNum + "条，明细如下：" );
            }
            msg.insert(0, "<br/>成功导入：" + successNum + "条" );
        }

        return msg.toString();
    }

    private Integer toInteger(String s){
        if (!NumberUtil.isNumber(s)){
            return 0;
        }
        return (int) Float.parseFloat(s);
    }

    private TStudyScore checkIsExist(String stuNo, Date examDate) {
        TStudyScore t = new TStudyScore();
        t.setStuNo(stuNo);
        t.setExamDate(examDate);
        List<TStudyScore> list = tStudyScoreMapper.selectTStudyScoreList(t);
        if (CollectionUtils.isEmpty(list)){
            return null;
        }
        return list.get(0);
    }
    @Override
    public List<String> queryLessonsByEduId(String stuNo){
    	return tStudyScoreMapper.queryLessonsByEduId(stuNo);
    }
    
    @Override
    public List<AvgExamSchoolRankVO> queryLastTwoLessonsByEduId(String stuNo){
    	return tStudyScoreMapper.queryLastTwoLessonsByEduId(stuNo);
    }
}
